import Axios from 'axios';
import qs from 'qs';
import CONFIG from '../config';
import { IConfigTypes, CustomSuccessData } from './index.d';
import { message, notification } from 'antd';
import { getToken, removeToken } from '../auth';

const http = Axios.create({
  baseURL: CONFIG.BASE_URL,
  timeout: CONFIG.TIMEOUT,
  withCredentials: true
})

const { SUCCESS: SUCCESS_CODE } = CONFIG.CODE;

http.interceptors.request.use(
  <T>(config: any) => {
    config.headers.Authorization = getToken();
    const _config: IConfigTypes = config.data?._config;
    const data: T = config.data?.params;
    config.data = _config?._formData ? qs.stringify(data) : data;
    return config
  },
  error => {
    const { response } = qs.parse(error);
    return commonErrorHandling(response)
  }
)

http.interceptors.response.use(
  (response: any) => {
    const { _backCommonErrorHandling, data: res, config } = response;
    const { code } = res;
    if (code === SUCCESS_CODE) {
      responseSuccess(res, config)
    } else if (!_backCommonErrorHandling && code !== SUCCESS_CODE) {
      return commonErrorHandling(res)
    }
    return res
  },
  error => {
    const { response } = qs.parse(error);
    return commonErrorHandling(response)
  }
)

export const $GET = <T, U = {}>(url: string, query?: U, _config?: IConfigTypes): Promise<CustomSuccessData<T>> => {
  return http.get(url, {
    params: {
      ...query,
      timer: new Date().getTime()  // 规避IE缓存
    },
    ..._config
  })
}

export const $POST = <T, U = {}>(url: string, data?: U, _config?: IConfigTypes): Promise<CustomSuccessData<T>> => {
  return http.post(url, {
    params: { ...data },
    _config
  })
}

export const $DELETE = <T, U = {}>(url: string, data?: U, _config?: IConfigTypes): Promise<CustomSuccessData<T>> => {
  return http.delete(url, {
    params: { ...data },
    ..._config
  })
}

export const $PUT = <T, U = {}>(url: string, data?: U, _config?: IConfigTypes): Promise<CustomSuccessData<T>> => {
  return http.put(url, {
    params: { ...data },
    _config
  })
}

// 常见的公共错误处理
function commonErrorHandling(response: any) {
  const code = response.code || response.status;
  switch (code) {
    case CONFIG.CODE.LOGIN_LOSE:
      notification.error({
        message: '登录失效请重新登录!',
      });
      removeToken();
      return window.location.replace('/login')
    default:
      notification.error({
        message: response.msg || CONFIG.MSG.DEFAULT_ERROE,
      })
  }

  return Promise.reject(response)
}

// 接口请求成功返回
function responseSuccess<T>(response: CustomSuccessData<T>, config: any) {
  if (config._msg) {
    const msg: string = typeof config._msg === "boolean" ? CONFIG.MSG.SUCCESS : config._msg;
    message.success(msg)
  }
  return response;
}
